之前我們實作了簡單的播放器,了解該如何播放聲音;前幾天介紹了檔案格式與基礎取樣知識,知道 Web 支援哪些格式的音檔,以及產生音檔背後的原理。接下來講講 Web 提供了哪些 API,可以讓使用者提供音檔,甚至用麥克風錄製聲音吧!
一共有三個相關的 Web API
API | description |
---|---|
Web RTC API (Web Real-Time Communications) | 瀏覽器間點對點的即時通訊,可以即時交換影音或任意的資料 |
Media Capture and Streams API | 提供方法操作包含影音的 MediaStream |
MediaStream Recording API | 提供方法取得 MediaStream、HTMLMediaElement 內含的資料以便進一步處理 (運算、解析、儲存..) |
這幾支 API 彼此是互相配合,以提供完整的影音串流操作。
MediaStream 是一個表示影音串流的物件,隸屬於 Media Capture and Streams API,只有一組 input、output,其包含了零至數個 MediaStreamTrack (影音軌),每個 MediaStreamTrack 包含一至數個 Channel (聲道)。
舉個例子:
[Input] ==> MediaStream ==> [Output]
MediaStream 可以從哪邊取得呢?以下有幾種方式:
Input | local / non-local | Description |
---|---|---|
getUserMedia | local | 從相機、麥克風等裝置使用 navigator.mediaDevices.getUserMedia() 取得資料 |
media element | non-local | <audio> , <video> 的 captureStream() 方法 |
Web Audio API | non-local | MediaStreamAudioSourceNode 產生的 stream |
WebRTC | non-local | 網路傳輸的 stream 並用 RTCPeerConnection API 取得 |
當然也可以用 new MediaStream()
建立空的 MediaStream,再把 MediaStreamTrack 塞進去就是了。
MediaStream 能被誰使用呢?以下有幾種方式:
Output | Description |
---|---|
media element | <audio> , <video> |
Web Audio API | MediaStreamAudioDestinationNode |
WebRTC | RTCPeerConnection API 取得 |
name | description | param | return |
---|---|---|---|
MediaStream() | constructor,建立新的 MediaStream | MediaStream / Array of MediaStreamTracks | MediaStream |
addTrack() | 加進一軌 | MediaStreamTrack | undefined |
removeTrack() | 移除一軌 | MediaStreamTrack | undefined |
clone() | 複製整個 MediaStream | none | MediaStream |
getTracks() | 返回包含所有 MediaStreamTrack 的陣列,不保證排序 | none | Array of MediaStreamTracks |
getAudioTracks() | 返回 MediaStreamTrack.kind 為 audio 的 MediaStreamTrack 陣列,不保證排序 | none | Array of MediaStreamTracks |
getVideoTracks() | 返回 MediaStreamTrack.kind 為 video 的 MediaStreamTrack 陣列,不保證排序 | none | Array of MediaStreamTracks |
getTrackById() | 返回 MediaStreamTrack.id 與參數 id 相同的 MediaStreamTrack | id string | MediaStreamTrack or null |
onaddtrack | event handler for addtrack ,新增 track 時觸發 |
||
onremovetrack | event handler for removetrack ,移除 track 時觸發 |
MediaDevices 是一個物件,可以取得與本機連結的麥克風、鏡頭、甚至螢幕等裝置。
name | description | param | return |
---|---|---|---|
ondevicechange | event hanlder for devicechange ,移除或連接新裝置到電腦時觸發 |
||
enumerateDevices() | 列舉出與電腦連接的所有裝置 | none | Promise,包含了 MediaDeviceInfo 物件的陣列 |
getSupportedConstraints() | 列舉出該瀏覽器 MediaStreamTrack 能識別的屬性值,詳情參考這篇 |
none | Object,只包含能識別的屬性值 (key: property, value: true) |
getUserMedia() | 從裝置取得資料並轉為指定格式的 MediaStream | MediaStreamConstraints | Promise with stream |
navigator.mediaDevices.getUserMedia({ audio: true })
.then(mediaStream => { .... })
稍微看了一下 API,看起來是沒辦法直接 new 一個 MediaStreamTrack 然後加到 MediaStream。
一定得先建立 MediaStream,取得 MediaStreamTrack 後透過 applyConstraints()
設定讓瀏覽器處理的參數理想值/可接受值 (例如:width: 300 - 600、sampleRate: 44100 ...),從回傳的 Promise 取得處理後的結果。
const constraints = {
width: {min: 640, ideal: 1280},
height: {min: 480, ideal: 720},
advanced: [
{width: 1920, height: 1280},
{aspectRatio: 1.333}
]
};
navigator.mediaDevices.getUserMedia({ video: true })
.then(mediaStream => {
const track = mediaStream.getVideoTracks()[0];
track.applyConstraints(constraints)
.then(() => { ... }
.catch(e => { ... }
}
name | description | param | return |
---|---|---|---|
applyConstraints() | 讓 MediaStreamTrack 根據指定屬性值進行處理 | MediaTrackConstraints | Promise |
getCapabilities() | 取得瀏覽器 MediaStreamTrack 支援的 constriant 以及有效的屬性值 | none | MediaTrackCapabilities |
getConstraints() | 取得 MediaStreamTrack 當前的屬性值 | none | MediaTrackConstraints |
getSettings() | 取得 MediaStreamTrack 當前的設定 | none | MediaTrackSettings |
clone() | 複製一個 MediaStreamTrack | none | MediaStreamTrack |
stop() | 將一個 MediaStreamTrack 停止並 detatch 串流源,一旦串流源沒有任何 track 使用就會完全停止 | none | none |
今天先到這邊,明天再繼續講其他相關的 API 吧~